﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TosObserver
{
    public abstract class TosFeedMonitor : IObserver<TosFeed>, IDisposable
    {
        // compiler will ask for overrides for them (in TosFeedMonitor descendant classes)
        public abstract void OnCompleted();
        public abstract void OnError(Exception error);
        public abstract void OnNext(TosFeed value);

        Dictionary<string, IDisposable> subscriptions = new Dictionary<string, IDisposable>();
        Dictionary<string, TosFeed> feeds = new Dictionary<string, TosFeed>();

        private string GetKey(string symbol, TOSTopic topic)
        {
            return symbol.ToUpper() + "#" + topic.Name;
        }

        public void Subscribe(string symbol, TOSTopic topic)
        {
            string key = GetKey(symbol, topic);
            if (subscriptions.ContainsKey(key))
                return;
            TosFeed feed = new TosFeed(symbol.ToUpper(), topic);
            feeds.Add(key, feed);
            IDisposable subscription = feed.Subscribe(this);
            subscriptions.Add(key, subscription);
        }

        public void UnSubscribe(string symbol, TOSTopic topic)
        {
            string key = GetKey(symbol, topic);
            IDisposable subscription;
            lock (subscriptions)
            {
                if (!subscriptions.ContainsKey(key))
                    return;
                subscription = subscriptions[key];
                subscriptions.Remove(key);
            }
            subscription.Dispose();
            TosFeed feed = feeds[key];
            feeds.Remove(key);
            feed.Dispose();
        }

        public void Dispose()
        {
            lock (subscriptions)
            {
                foreach (string key in subscriptions.Keys)
                {
                    subscriptions[key].Dispose();
                    feeds[key].Dispose();
                }
                subscriptions.Clear();
            }
            feeds.Clear();
        }
    }
}
